﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace 数理逻辑的程序实现
{
    /// <summary>二进制数类</summary>
    class BinaryNumber : IEquatable<BinaryNumber>
    {
        /// <summary>这个二进制数有多少位</summary>
        public int Count { get; set; }
        /// <summary>二进制数</summary>
        /// <param name="count">这个二进制数用几位来表示，不足的在左边补0</param>
        public BinaryNumber( int count )
        {
            this.Count = count;
        }
        public BinaryNumber( List<bool> bs )
            : this( bs.Count )
        {
            Binary = bs;
        }
        public bool this[int index]
        {
            get
            {
                return binary[index];
            }
        }
        List<int> trueBit = new List<int>();
        /// <summary>1的占位</summary>
        public List<int> TrueBit
        {
            get { return trueBit; }
        }

        List<int> falseBit = new List<int>();
        /// <summary>0的占位</summary>
        public List<int> FalseBit
        {
            get { return falseBit; }
        }

        List<bool> binary = new List<bool>();
        /// <summary>用0，1将此二进制数表示出来,false为0，true为1</summary>
        public List<bool> Binary
        {
            get { return binary; }
            set
            {
                //binary = value; 不能直接这样赋值，因为List<>是引用类型
                for ( int i = 0 ; i < value.Count ; i++ )
                {
                    binary.Add( value[i] );
                    if ( value[i] )
                    {
                        trueBit.Add( i );
                    }
                    else
                    {
                        falseBit.Add( i );
                    }
                }

            }
        }

        private int decimalnumber;
        /// <summary>十进制数</summary>
        public int DecimalNumber
        {
            get { return decimalnumber; }
            set
            {
                this.decimalnumber = value;
                trueBit.Clear();
                falseBit.Clear();
                binary.Clear();

                if ( Count == 1 )
                {
                    if ( value == 0 )
                    {
                        binary.Add( false );
                        falseBit.Add( 0 );
                    }
                    else
                    {
                        binary.Add( true );
                        trueBit.Add( 0 );
                    }
                }
                else
                {
                    int temp , num = decimalnumber;
                    int index = 0;
                    //int[] array = new int[Count];
                    List<int> array = new List<int>();
                    //把给定的值转化为二进制，存进array数组中，注意这时还是和正确的顺序相反
                    do
                    {
                        //array[index] = num % 2;
                        array.Add( num % 2 );
                        temp = num / 2;
                        index++;
                        if ( temp == 1 )
                            //array[index] = 1;
                            array.Add( 1 );
                        if ( temp == 0 )
                            array.Add( 0 );
                        num = temp;
                    } while ( temp != 1 && temp != 0 );
                    //在不足变量个数的位数时，补充成和变量一样的个数
                    while ( index < Count - 1 )
                    {
                        index++;
                        //array[index] = 0;
                        array.Add( 0 );
                    }
                    //把数组倒序，就是真的十进制对应两进制了
                    array.Reverse();
                    //把给为情况存入falseBit和trueBit和binary中
                    for ( int i = 0 ; i < Count ; i++ )
                    {
                        if ( array[i] == 0 )
                        {
                            falseBit.Add( i );
                            binary.Add( false );
                        }
                        else
                        {
                            trueBit.Add( i );
                            binary.Add( true );
                        }
                    }

                }
            }
        }

        public BinaryNumber Clone()
        {
            return new BinaryNumber( this.binary );
        }

        public bool Equals( BinaryNumber other )
        {
            if ( this.Count != other.Count )
                return false;
            for ( int i = 0 ; i < Count ; i++ )
            {
                if ( Binary[i] != other.Binary[i] )
                    return false;
            }
            return true;
        }
        public bool Equals( List<bool> bin )
        {
            if ( this.Count != bin.Count )
                return false;
            for ( int i = 0 ; i < Count ; i++ )
            {
                if ( this.Binary[i] != bin[i] )
                    return false;
            }
            return true;
        }

    }
}
